package com.coupon.couponbatchsend100w.utils;

import java.util.List;
import java.util.Objects;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.Executor;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * @auther zzyy
 * @create 2024-04-02 17:18
 */
public class TaskDisposeUtils
{
// 使用方式：TaskDisposeUtils.send(coupons,threadPool,TaskDisposeUtils::disposeTask);
// 只要在类中发现一些方法，形参返回值相同，仅方法名不同，就把他们统一简写成：类名::方法名的形式，
// 这里disposeTask类方法都有形参，没返回值，符合consumer消费型接口的形式，所以send是Consumer<? super T> consumer
// 泛型 T 可以是任何类型（优惠券、短信、注册码等）。
    public static <T> void send(List<T> taskList, Executor threadPool,Consumer<? super T> consumer)
            throws InterruptedException
    {
        if (taskList == null || taskList.size() == 0) //循环中遍历的是集合中的每个元素（for (T couponOrShortMsg : taskList)），然后把单个元素传给 disposeTask 方法处理。
        //task 参数代表的是集合中的单个任务对象（比如一条优惠券、一条短信）
        {
            return;
        }

        if(Objects.isNull(consumer))
        {
            return;
        }

        CountDownLatch countDownLatch = new CountDownLatch(taskList.size());
        for (T couponOrShortMsg : taskList) //这里的T可以是优惠券、激活码、积分豆……
        {
            threadPool.execute(() ->
            {
                try
                {
                    consumer.accept(couponOrShortMsg);
                } finally {
                    countDownLatch.countDown();
                }
            });
        }
        countDownLatch.await();
    }


    //============================================
    // 使用方式：TaskDisposeUtils.send(coupons,threadPool,TaskDisposeUtils::disposeTask);
    // lambda体,仅仅是调用方法methodA，没再做其它逻辑，即methodA正好是lambda体的实现逻辑
    //  即methodA                          正好是         lambda体的实现逻辑
    //  consumer.accept(couponOrShortMsg);                 sysout业务逻辑

    public static void disposeTask(String task) //下发优惠券任务v1，形参task代表几条
    {
        //【%s】下发成功", task 的作用是：将 task(每个优惠券/激活码的序号)的值替换到 %s 的位置，生成一个新字符串。
        System.out.println(String.format("【%s】disposeTask下发优惠卷或短信成功", task));
    }


    //只要在类中发现一些方法，形参返回值相同，仅方法名不同，就把他们统一简写成：类名::方法名的形式————
    public static void disposeTaskV2(String task)
    {
        System.out.println(String.format("【%s】disposeTask下发邮件成功", task));
    }

    public static void disposeTaskV3(String task)
    {
        System.out.println(String.format("【%s】disposeTask下发注册码成功", task));
    }

    public static void disposeTaskV4(String task)
    {
        System.out.println(String.format("【%s】disposeTask下发XXXXXXX成功", task));
    }
//    这些下发操作的形参都是string（优惠券、邮件、方法注册码等），返回值都是void，可以用lambda表达式 -> 方法引用
//    如果一个方法的入参和返回值类型与某个函数式接口中抽象方法的入参和返回值类型一致、
//    且方法体就是lambda体的实现逻辑（如下发激活码/注册码…），可以简化为：类名称::静态方法名
//    即TaskDisposeUtils::disposeTaskV2

//    所谓方法引用：就是某个方法签名（即形参列表+返回值）和接口（比如consumer）恰好一致，就可以直接简化为方法引用——类名::静态方法名

//     总之，只要形参和返回值一样，都可以浓缩成一个写法——类名::方法名

}
